import { XYZ_CONFIG, PLAYERINFO_CONFIG } from "../config.js";
export function update(){
    let xyz_ver = XYZ_CONFIG.get("ver");
    if (xyz_ver.toString() == '1,5,0'){
        try{
            update200();
        }catch(e){
            logger.error(e);
        }
    }
}

function update200(){
    if (!File.exists("./plugins/xyz/backup/xyz_1.5.0.json")){
        File.createDir("./plugins/xyz/backup/");
        File.copy("./plugins/xyz/data/xyz.json", "./plugins/xyz/backup/xyz_1.5.0.json");
    }else{
        File.delete("./plugins/xyz/backup/xyz_1.5.0.json");
        File.copy("./plugins/xyz/data/xyz.json", "./plugins/xyz/backup/xyz_1.5.0.json");
    }
    
    let newXyzData = {};
    newXyzData['ver'] = [2,0,0];
    let oldData = JSON.parse(XYZ_CONFIG.read());
    let oldDateEntries = Object.entries(oldData);
    let lossPlayers = [];

    // playerInfo.json
    let new_playerInfos = PLAYERINFO_CONFIG.get("players");
    for (let key in oldData){
        if (key == 'public' || key == 'ver'){continue;}
        if (oldData[key].playerName == undefined){continue;}
        let playerInfo = findPlayerInfo(oldData[key].playerName);
        if (playerInfo == null){
            lossPlayers.push(oldData[key].playerName);
            continue;
        }
        if (new_playerInfos[playerInfo.xuid] != null){
            continue;
        }
        new_playerInfos[playerInfo.xuid] = playerInfo;
    }
    PLAYERINFO_CONFIG.set("players", new_playerInfos);
    let playerInfoValues = Object.values(new_playerInfos);
    
    // public
    let old_public = oldData['public'];
    let new_public = {};
    for (let category in old_public){
        if (category == 'playerName'){continue;}
        let newWarpList = [];
        let nameList = [];
        for (let old_warp of old_public[category]){
            let warp = parseOldWarpStr(old_warp[0]);
            if (warp == null){continue;} // 未被解析的坐标字符串
            let realName = old_warp[1];
            let playerInfo = playerInfoValues.find(info=>info.realName == realName);
            if (playerInfo == null){continue;} // 玩家信息丢失
            warp = {...playerInfo, ...warp};
            let i = 0;
            let ori_name = warp.name;
            while (nameList.includes(warp.name)){
                i++;
                warp.name = ori_name + `_${i}`;
            }
            newWarpList.push(warp);
            nameList.push(warp.name);
        }
        new_public[category] = newWarpList;
    }
    newXyzData['public'] = new_public;

    // person
    let new_person = {};
    for (let xuid in oldData){
        if (xuid == 'public' || xuid == 'ver'){continue;}
        let realName = oldData[xuid].playerName;
        if (realName == null){continue;}
        let playerInfo = playerInfoValues.find(info=>info.realName == realName);
        if (playerInfo == null){continue;}

        new_person[playerInfo.xuid] = {};

        for (let category in oldData[xuid]){
            if (category == 'playerName'){continue;}
            let newWarpList = [];
            let nameList = [];
            for (let old_warp of oldData[xuid][category]){
                let warp = parseOldWarpStr(old_warp);
                if (warp == null){continue;} // 未被解析的坐标字符串
                let i = 0;
                let ori_name = warp.name;
                while (nameList.includes(warp.name)){
                    i++;
                    warp.name = ori_name + `_${i}`;
                }
                newWarpList.push(warp);
                nameList.push(warp.name);
            }
            new_person[playerInfo.xuid][category] = newWarpList;
        }
    }
    newXyzData['person'] = new_person;
    XYZ_CONFIG.write(JSON.stringify(newXyzData, undefined, 4));
    if (lossPlayers.length > 0){
        logger.warn(`[坐标记录升级] 1.5.0版本之前的玩家数据将被舍弃(${lossPlayers.length}名玩家):`);
        logger.warn(lossPlayers.join(", "));
    }
    logger.warn("● 坐标记录(XYZ) 2.0.0 版本数据格式升级成功");
         

    function findPlayerInfo(realName){
        let res = {};
        let xuid = data.name2xuid(realName);
        if (xuid != null && xuid != ""){
            res.realName = realName;
            res.xuid = xuid;
            res.uuid = data.name2uuid(realName);
            return res;
        }
        let entry = oldDateEntries.find(oldPlayerData=>oldPlayerData[1].playerName == realName);
        if (entry != undefined){
            if (/^\d+$/.test(entry[0])){
                res.realName = realName;
                res.xuid = entry[0];
                return res;
            }
        }
        return null;
    }
    
    function parseOldWarpStr(xyzlogstr){
        let PosStringReg = /§3<§r(.*)§3>§a (-?\d*), (-?\d*), (-?\d*), (§e主世界|§c下届|§3末地)(.*)/;
        let warp = {pos:{x:0, y:100, z:0, dimid:0},name:""};
        let regTemp = PosStringReg.exec(xyzlogstr);
        if (regTemp == null){
            return null;
        }
    
        warp.name = regTemp[1];
        if (warp.name[1] == "✈"){
            warp.tpAllow = true;
            warp.name = warp.name.slice(2);
        }else{
            warp.tpAllow = false;
        }
        warp.time = new Date().getTime();
        warp.pos.x = Number(regTemp[2]);
        warp.pos.y = Number(regTemp[3]);
        warp.pos.z = Number(regTemp[4]);
        
    
        if (regTemp[5] == "§e主世界"){
            warp.pos.dimid = 0;
        }else if (regTemp[5] == "§c下届"){
            warp.pos.dimid = 1;
        }else if (regTemp[5] == "§3末地"){
            warp.pos.dimid = 2;
        }else{
            return null;
        }
        return warp;
    }
}

